<template>
    <div class="product-edit">
        <el-card class="box-card">
            <template #header>
                <div class="clearfix">
                    <span>{{ isEdit ? '商品编辑' : '商品上架' }}</span>
                </div>
            </template>
            <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
                <!-- 基本信息 -->
                <el-divider content-position="left">基本信息</el-divider>
                <el-form-item label="商品名称" prop="title">
                    <el-input v-model="form.title" placeholder="请输入商品名称"></el-input>
                </el-form-item>
                <el-form-item label="商品副标题" prop="subtitle">
                    <el-input v-model="form.subtitle" placeholder="请输入商品副标题"></el-input>
                </el-form-item>
                <el-form-item label="品牌" prop="brand">
                    <el-input v-model="form.brand" placeholder="请输入商品品牌"></el-input>
                </el-form-item>
                <el-form-item label="商品分类" prop="categoryPath">
                    <el-cascader v-model="form.categoryPath" :options="categories" :props="{
                        checkStrictly: false,
                        value: 'id',
                        label: 'name',
                        children: 'children',
                        emitPath: true,
                        changeOnSelect: false
                    }" placeholder="请选择商品分类" @change="handleCategoryChange"></el-cascader>
                </el-form-item>

                <!-- 价格/库存 -->
                <el-divider content-position="left">价格/库存</el-divider>
                <el-form-item label="销售价" prop="price">
                    <el-input-number v-model="form.price" :precision="2" :step="0.1" :min="0.01"
                        autocomplete="off"></el-input-number>
                </el-form-item>
                <el-form-item label="原价" prop="originalPrice">
                    <el-input-number v-model="form.originalPrice" :precision="2" :step="0.1" :min="0"
                        autocomplete="off"></el-input-number>
                </el-form-item>
                <el-form-item label="库存" prop="stock">
                    <el-input-number v-model="form.stock" :min="0" autocomplete="off"></el-input-number>
                </el-form-item>

                <!-- 图片信息 -->
                <el-divider content-position="left">图片信息</el-divider>
                <!-- 主图上传 -->
                <el-form-item label="主图" prop="mainImage">
                    <el-upload class="avatar-uploader" :action="ossUploadHost" :data="ossUploadData"
                        :show-file-list="false" :on-success="handleMainImageSuccess"
                        :before-upload="beforeMainImageUpload" :http-request="ossUploadRequest">
                        <template v-if="form.mainImage">
                            <div class="avatar-wrapper">
                                <img :src="form.mainImage" class="avatar">
                                <span class="el-upload-list_item-status-label">
                                    <el-icon class="el-icon-upload-success">
                                        <UploadFilled />
                                    </el-icon>
                                </span>
                                <div class="avatar-actions">
                                    <el-icon @click="handleMainImagePreview">
                                        <ZoomIn />
                                    </el-icon>
                                    <el-icon @click.stop="handleMainImageRemove">
                                        <Delete />
                                    </el-icon>
                                </div>
                            </div>
                        </template>
                        <el-icon v-else class="avatar-uploader-icon">
                            <Plus />
                        </el-icon>
                    </el-upload>
                </el-form-item>

                <!-- 图片集上传 -->
                <el-form-item label="图片集" prop="images">
                    <el-upload list-type="picture-card" :file-list="imageList" :on-preview="handlePictureCardPreview"
                        :on-remove="handleRemove" :before-upload="beforeImagesUpload" :on-success="handleImagesSuccess"
                        :http-request="ossUploadRequest" multiple>
                        <el-icon>
                            <Plus />
                        </el-icon>
                    </el-upload>
                    <!-- 图片预览弹窗 -->
                    <el-dialog v-model="dialogVisible" title="图片预览" width="40%" destroy-on-close :z-index="3000"
                        append-to-body>
                        <img width="100%" :src="dialogImageUrl" alt="预览图">
                    </el-dialog>
                </el-form-item>

                <!-- 商品详情 -->
                <el-divider content-position="left">商品详情</el-divider>
                <el-form-item>
                    <el-input type="textarea" :rows="4" placeholder="请输入商品详情" v-model="form.description"></el-input>
                </el-form-item>

                <!-- 其他设置 -->
                <el-form-item label="商品状态" prop="status">
                    <el-radio-group v-model="form.status">
                        <el-radio :label="1">上架</el-radio>
                        <el-radio :label="2">下架</el-radio>
                    </el-radio-group>
                </el-form-item>

                <!-- 提交按钮 -->
                <el-form-item>
                    <el-button type="primary" @click="submitForm()">{{ isEdit ? '保存修改' : '立即创建' }}</el-button>
                    <el-button v-if="isEdit" @click="goBack">返回列表</el-button>
                    <el-button v-else @click="resetForm()">重置</el-button>
                </el-form-item>
            </el-form>
        </el-card>
    </div>
</template>

<script setup lang="ts">
// 1. 导入API接口
import { getCategoryTree } from '@/api/category'
import { getProductDetail, saveProduct, getOssPolicy } from '@/api/product'

// 2. 导入Element Plus组件和图标
import {
    ElCard, ElForm, ElFormItem, ElInput, ElCascader,
    ElDivider, ElInputNumber, ElUpload, ElDialog,
    ElRadioGroup, ElRadio, ElButton, ElMessage, ElIcon
} from 'element-plus'
import {
    Plus, // 加号图标
    ZoomIn, // 放大预览图标
    Delete, // 删除图标
    UploadFilled // 上传成功图标
} from '@element-plus/icons-vue'

// 3. 导入Vue核心API
import { ref, reactive, onMounted, watch, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'

// 4. 类型定义（优化类型安全）
interface ProductForm {
    id: string
    title: string
    subtitle: string
    brand: string
    categoryId: string // 最终提交的分类ID（三级分类）
    categoryPath: (string | number)[] // 级联选择的原始路径（如 [1,2,3]）
    mainImage: string // 主图OSS URL
    images: string // 图片集OSS URL（逗号分隔）
    description: string
    price: number // 销售价
    originalPrice: number // 原价
    stock: number // 库存
    status: 1 | 2 // 1=上架，2=下架
}

interface ImageFile {
    uid: string
    name: string
    url?: string // OSS图片URL（必须赋值才能显示预览）
    raw: File // 原始文件
    response?: { key?: string } // OSS上传响应（XML解析后提取key）
}

// 5. 状态管理
const route = useRoute()
const router = useRouter()
const formRef = ref<InstanceType<typeof ElForm>>() // 表单Ref
const isEdit = ref(false) // 是否编辑模式
const categories = ref<any[]>([]) // 分类树形结构
const imageList = ref<ImageFile[]>([]) // 图片集列表（带类型）
const dialogImageUrl = ref('') // 预览弹窗图片URL
const dialogVisible = ref(false) // 预览弹窗显示状态

// OSS上传配置
const ossUploadHost = ref('')


const ossUploadData = ref<{
    OSSAccessKeyId: string
    policy: string
    Signature: string
    dir: string
    host: string
    expire: number
    key?: string // 上传文件的OSS路径（动态生成）
}>({})

// 表单数据（初始值）- 注意categoryPath为数组类型
const form = reactive<ProductForm>({
    id: '',
    title: '',
    subtitle: '',
    brand: '',
    categoryId: '',
    categoryPath: [], // 初始为空数组，与ElCascader匹配
    mainImage: '',
    images: '',
    description: '',
    price: 0.01, // 默认最小销售价（避免验证失败）
    originalPrice: 0,
    stock: 0,
    status: 1 // 默认上架
})

// 6. 表单验证规则
const rules = reactive({
    title: [
        { required: true, message: '请输入商品名称', trigger: 'blur' },
        { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
    ],
    categoryPath: [
        { required: true, message: '请选择商品分类', trigger: 'change' },
        {
            validator: (rule: any, value: (string | number)[], callback: (err?: Error) => void) => {
                if (!value || value.length !== 3) {
                    callback(new Error('请选择第三级别商品分类'))
                } else {
                    callback()
                }
            }, trigger: 'change'
        }
    ],
    price: [
        { required: true, message: '请输入商品销售价', trigger: 'blur' },
        { type: 'number', min: 0.01, message: '销售价不能小于0.01', trigger: 'blur' }
    ],
    stock: [
        { required: true, message: '请输入商品库存', trigger: 'blur' },
        { type: 'number', min: 0, message: '库存不能为负数', trigger: 'blur' }
    ],
    mainImage: [
        { required: true, message: '请上传商品主图', trigger: 'change' }
    ]
})

// 7. 核心业务逻辑
/**
 * 加载分类树形结构
 */
const loadCategories = async () => {
    try {
        const res = await getCategoryTree()
        if (res.code === 0) {
            // 清理空children（避免级联选择器异常）
            const cleanCategoryChildren = (list: any[]) => {
                list.forEach(item => {
                    // 确保分类ID为字符串（与ElCascader value类型匹配）
                    item.id = String(item.id)
                    if (Array.isArray(item.children) && item.children.length === 0) {
                        delete item.children
                    } else if (Array.isArray(item.children)) {
                        cleanCategoryChildren(item.children)
                    }
                })
            }
            cleanCategoryChildren(res.data)
            categories.value = res.data
        }
    } catch (error) {
        ElMessage.error("获取商品分类失败")
        console.error('分类加载错误:', error)
    }
}

/**
 * 加载商品详情（编辑模式）
 */
const loadProductData = async (id: number) => {
    try {
        const res = await getProductDetail(id)
        if (res.code === 0) {
            const product = res.data
            form.mainImage = product.main_image || '';
            // 处理分类路径：后端返回 ",1,2,3," → 转为 [1,2,3]（数字数组）
            const categoryPathArr = product.categoryPath
                ? product.categoryPath.replace(/^,|,$/g, '').split(',').filter(Boolean).map(Number)
                : []

            // 赋值基础信息（保持categoryPath原始格式）
            Object.assign(form, {
                ...product,
                categoryPath: categoryPathArr,
                price: product.price || 0.01, // 避免价格为0导致验证失败
                stock: product.stock || 0
            })

            // 处理图片集：后端返回 "url1,url2" → 转为ImageFile数组（确保url存在）
            if (product.images) {
                imageList.value = product.images.split(',')
                    .filter(url => url.trim()) // 过滤空URL
                    .map((url: string) => ({
                        uid: Date.now() + Math.random().toString(36).substr(2, 9),
                        name: url.split('/').pop() || 'image',
                        url // 关键：赋值url才能显示预览
                    }))
                // 同步更新form.images
                form.images = imageList.value.map(item => item.url).join(',')
            }
        } else {
            ElMessage.error(res.msg || '获取商品详情失败')
            goBack()
        }
    } catch (error) {
        ElMessage.error("获取商品详情失败")
        console.error('商品详情加载错误:', error)
        goBack()
    }
}

/**
 * 分类选择变化（提取三级分类ID，不修改原始categoryPath）
 */
const handleCategoryChange = (value: (string | number)[]) => {
    if (value && value.length === 3) {
        form.categoryId = String(value[2]) // 取最后一级ID（转为字符串，避免类型问题）
        console.log('当前选择分类ID:', form.categoryId, '路径:', value)
    }
}

/**
 * 获取OSS上传签名（避免签名过期）
 */
const getOssPolicyData = async () => {
    try {
        const res = await getOssPolicy()
        if (res.code === 0) {
            ossUploadHost.value = res.data.host
            ossUploadData.value = {
                OSSAccessKeyId: res.data.accessid,
                policy: res.data.policy,
                Signature: res.data.signature,
                dir: res.data.dir,
                host: res.data.host,
                expire: res.data.expire
            }
            console.log('OSS签名获取成功:', ossUploadData.value)
        } else {
            ElMessage.error(res.msg || '获取OSS上传权限失败')
        }
    } catch (error) {
        ElMessage.error("获取OSS上传权限失败")
        console.error('OSS签名错误:', error)
    }
}

const parseOssXmlResponse = (xmlStr: string): string => {
    try {
        if (!xmlStr.trim()) return ''; // 处理空响应

        const parser = new DOMParser();
        const xmlDoc = parser.parseFromString(xmlStr, 'text/xml');

        const keyNode = xmlDoc.querySelector('Key');
        if (keyNode && keyNode.textContent) {
            return keyNode.textContent;
        }

        // 处理可能的错误响应
        const errorNode = xmlDoc.querySelector('Code');
        if (errorNode) {
            console.error('OSS上传错误:', xmlDoc.querySelector('Message')?.textContent);
            return '';
        }

        return '';
    } catch (e) {
        console.error('解析OSS响应XML失败:', e);
        return '';
    }
}

/**
 * 主图上传前校验
 */
const beforeMainImageUpload = async (file: File) => {
    await getOssPolicyData() // 确保先获取签名
    // 校验文件类型
    const isImage = file.type.startsWith('image/')
    if (!isImage) {
        ElMessage.error('请上传图片格式文件（JPG/PNG等）')
        return false
    }
    // 校验文件大小（2MB）
    const isLt2M = file.size / 1024 / 1024 < 2
    if (!isLt2M) {
        ElMessage.error('上传图片大小不能超过 2MB')
        return false
    }
    // 生成唯一文件名（避免OSS文件覆盖）
    const suffix = file.name.substring(file.name.lastIndexOf('.'))
    const filename = `${Date.now()}_${Math.floor(Math.random() * 10000)}${suffix}`
    ossUploadData.value.key = `${ossUploadData.value.dir}main/${filename}` // 主图单独放main目录
    return true
}

/**
 * 图片集上传前校验
 */
const beforeImagesUpload = async (file: File) => {
    await getOssPolicyData() // 确保先获取签名
    // 校验文件类型
    const isImage = file.type.startsWith('image/')
    if (!isImage) {
        ElMessage.error('请上传图片格式文件（JPG/PNG等）')
        return false
    }
    // 校验文件大小（2MB）
    const isLt2M = file.size / 1024 / 1024 < 2
    if (!isLt2M) {
        ElMessage.error('上传图片大小不能超过 2MB')
        return false
    }
    // 生成唯一文件名
    const suffix = file.name.substring(file.name.lastIndexOf('.'))
    const filename = `${Date.now()}_${Math.floor(Math.random() * 10000)}${suffix}`
    ossUploadData.value.key = `${ossUploadData.value.dir}gallery/${filename}` // 图片集放gallery目录
    return true
}

/**
 * 主图上传成功回调
 */
const handleMainImageSuccess = (res: { key?: string }, file: ImageFile) => {
    // 优先使用解析的OSS响应key，其次用预设key
    const ossKey = res.key || ossUploadData.value.key || ''
    form.mainImage = `${ossUploadHost.value}/${ossKey}` // 拼接完整URL
    console.log('主图上传成功，URL:', form.mainImage)
    ElMessage.success('主图上传成功')
}

/**
 * 图片集上传成功回调（关键修复：确保imageList响应式更新）
 */
const handleImagesSuccess = (res: { key?: string }, file: ImageFile) => {
    // 解析OSS响应key（处理XML响应）
    const ossKey = res.key || (typeof res === 'string' ? parseOssXmlResponse(res) : '') || ossUploadData.value.key || ''
    const imageUrl = `${ossUploadHost.value}/${ossKey}`

    // 1. 找到当前上传的文件，更新url（确保响应式）
    const targetIndex = imageList.value.findIndex(item => item.uid === file.uid)
    if (targetIndex !== -1) {
        imageList.value[targetIndex].url = imageUrl // 直接修改数组元素，触发响应式
    } else {
        imageList.value.push({
            ...file,
            url: imageUrl
        })
    }

    // 2. 同步更新form.images（逗号分隔URL）
    form.images = imageList.value
        .filter(item => item.url) // 过滤未上传成功的文件
        .map(item => item.url)
        .join(',')

    console.log('图片集上传成功，当前列表:', imageList.value, 'form.images:', form.images)
    ElMessage.success('图片上传成功')
}

/**
 * 图片集预览（确保URL有效）
 */
const handlePictureCardPreview = async (file: ImageFile) => {
    if (file.url) {
        dialogImageUrl.value = file.url
        dialogVisible.value = true // 直接设置为true
        console.log('预览图片URL:', file.url)
    } else {
        ElMessage.warning('图片尚未上传完成，无法预览')
    }
}

/**
 * 图片集删除（同步更新form.images）
 */
const handleRemove = (file: ImageFile) => {
    // 从列表中移除（filter返回新数组，确保响应式）
    imageList.value = imageList.value.filter(item => item.uid !== file.uid)
    // 同步更新form.images
    form.images = imageList.value
        .filter(item => item.url)
        .map(item => item.url)
        .join(',')
    console.log('删除图片后，form.images:', form.images)
}

/**
 * 主图预览
 */
const handleMainImagePreview = () => {
    if (form.mainImage) {
        dialogImageUrl.value = form.mainImage;
        dialogVisible.value = true;
    } else {
        ElMessage.warning('请先上传主图');
    }
}

/**
 * 主图删除
 */
const handleMainImageRemove = () => {
    form.mainImage = ''
}

const ossUploadRequest = (option: {
    file: File
    onSuccess: (res: any, file: any) => void
    onError: (err: string) => void
}) => {
    const { file, onSuccess, onError } = option
    const formData = new FormData()
    // 拼接OSS上传参数
    formData.append('key', ossUploadData.value.key || '')
    formData.append('OSSAccessKeyId', ossUploadData.value.OSSAccessKeyId || '')
    formData.append('policy', ossUploadData.value.policy || '')
    formData.append('Signature', ossUploadData.value.Signature || '')
    formData.append('file', file)

    // 发起XMLHttpRequest请求
    const xhr = new XMLHttpRequest()
    xhr.open('POST', ossUploadData.value.host || '', true)
    xhr.withCredentials = false // OSS上传不需要跨域凭证
    xhr.responseType = 'text' // OSS返回XML，设置响应类型为文本

    // 上传成功回调（解析XML获取key）
    xhr.onload = () => {
        if (xhr.status >= 200 && xhr.status < 300) {
            const xmlResponse = xhr.responseText
            const ossKey = parseOssXmlResponse(xmlResponse) // 解析XML提取key
            console.log('OSS上传成功，响应XML:', xmlResponse, '提取key:', ossKey)
            onSuccess({ key: ossKey }, file) // 将key传给success回调
        } else {
            const errorMsg = `上传失败：${xhr.statusText}（状态码：${xhr.status}）`
            onError(errorMsg)
            ElMessage.error(errorMsg)
        }
    }

    // 上传失败回调
    xhr.onerror = () => {
        const errorMsg = '网络错误，上传失败'
        onError(errorMsg)
        ElMessage.error(errorMsg)
    }

    // 发送请求
    xhr.send(formData)
}

const submitForm = async () => {
    if (!formRef.value) return;
    formRef.value.validate(async (valid) => {
        if (valid) {
            try {
                const categoryPathStr = ',' + form.categoryPath.join(',') + ',';
                const submitData = {
                    ...form,
                    categoryId: form.categoryPath[form.categoryPath.length - 1],
                    categoryPath: categoryPathStr
                };

                // 仅调用一次保存接口
                const res = await saveProduct(submitData);
                if (res.code === 0) {
                    ElMessage.success('保存成功');
                    resetForm();
                    goBack();
                } else {
                    ElMessage.error(res.msg || '保存失败');
                }
            } catch (error) {
                ElMessage.error('保存失败，请稍后再试');
                console.error('保存错误:', error);
            }
        }
    });
};

/**
 * 重置表单（完全清空状态）
 */
const resetForm = () => {
    if (formRef.value) {
        formRef.value.resetFields()
        // 额外重置图片相关字段
        form.mainImage = ''
        form.images = ''
        imageList.value = [] // 清空图片集列表
        dialogImageUrl.value = ''
        dialogVisible.value = false
        // 重置分类相关字段
        form.categoryPath = []
        form.categoryId = ''
        console.log('表单重置完成')
    }
}

/**
 * 返回列表页
 */
const goBack = () => {
    router.go(-1)
}

// 8. 页面挂载时初始化
onMounted(async () => {
    await loadCategories()

    // 检查是否为编辑模式（路由参数是否有id）
    const productId = route.params.id
    if (productId && typeof productId === 'string') {
        isEdit.value = true
        await loadProductData(Number(productId))
    }
})

// 调试用：监听imageList变化
watch(imageList, (newVal) => {
    console.log('imageList变化:', newVal)
}, { deep: true })

// 调试用：监听form.categoryPath变化
watch(() => form.categoryPath, (newVal) => {
    console.log('分类路径变化:', newVal)
}, { deep: true })
</script>

<style scoped>
.product-edit {
    padding: 20px;
    background-color: #f5f7fa;
}

.box-card {
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.08);
    border-radius: 8px;
}

/* 主图上传样式 */
.avatar-uploader {
    width: 148px;
    height: 148px;
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: border-color 0.3s;
}

.avatar-uploader:hover {
    border-color: #409eff;
}

.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 148px;
    height: 148px;
    line-height: 148px;
    text-align: center;
}

.avatar {
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* 保持图片比例 */
    display: block;
}

/* 主图预览/删除操作区 */
.avatar-wrapper {
    position: relative;
    width: 100%;
    height: 100%;
    z-index: 1;
    /* 确保容器层级正常 */

}

.avatar-actions {
    display: none;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.5);
    color: #fff;
    align-items: center;
    justify-content: center;
    gap: 20px;
    font-size: 22px;
    z-index: 2;
    /* 高于图片和上传成功标记 */
    pointer-events: auto;
    /* 允许点击（默认可能被父元素遮挡） */
}

.avatar-wrapper:hover .avatar-actions {
    display: flex;
}

.avatar-actions el-icon {
    cursor: pointer;
    transition: color 0.2s;
}

.avatar-actions el-icon:hover {
    color: #409eff;
}

/* 主图上传成功标记 */
.el-upload-list_item-status-label {
    position: absolute;
    right: 0;
    top: 0;
    width: 32px;
    height: 32px;
    z-index: 1;
    /* 低于操作区 */
    pointer-events: none;
    /* 不拦截点击事件 */
}

.el-upload-list_item-status-label::after {
    content: "";
    position: absolute;
    right: 0;
    top: 0;
    width: 0;
    height: 0;
    border-top: 32px solid #13ce66;
    border-left: 32px solid transparent;
    z-index: 10;
}

.el-icon-upload-success {
    position: absolute;
    right: 2px;
    top: 2px;
    font-size: 14px;
    color: #fff;
    z-index: 11;
}

/* 隐藏上传成功标记的hover效果 */
.avatar-wrapper:hover .el-upload-list_item-status-label {
    display: none;
}

/* 图片集预览图样式（确保显示） */
.el-upload-list--picture-card .el-upload-list__item {
    width: 148px;
    height: 148px;
}

.el-upload-list__item-thumbnail {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
</style>